/**
 * 
 */
package com.shine.icis.dao.imp;

import java.util.List;

import org.hibernate.Query;

import com.shine.icis.dao.IFlowDAO;
import com.shine.icis.dao.imp.BaseHibernateDAO;
import com.shine.icis.hbean.FlowDef;
import com.shine.icis.hbean.FlowIns;
import com.shine.icis.hbean.FlowNode;
import com.shine.icis.hbean.NodeAssign;
import com.shine.icis.hbean.TaskIns;

/**
 * @author zsy
 *
 */
public class FlowDAO extends BaseHibernateDAO implements IFlowDAO {
	
	@Override
	public TaskIns findTaskById(String id) {
		TaskIns sl = (TaskIns)getSession().get(TaskIns.class, id);
		return sl;
	}
	
	@Override
	public FlowNode findFlowNodeById(String id) {
		FlowNode sl = (FlowNode)getSession().get(FlowNode.class, id);
		return sl;
	}
	
	@Override
	public FlowIns findFlowInsById(String id) {
		FlowIns fi = (FlowIns)getSession().get(FlowIns.class, id);
		return fi;
	}
	
	@Override
	public FlowDef findFlowDefById(String id) {
		FlowDef fd = (FlowDef)getSession().get(FlowDef.class, id);
		return fd;
	}
	
	@Override
	public void deleteFlowNode(String id) {
		FlowNode node = findFlowNodeById(id);
		if (node == null) {
			return;
		}
		//删除流程实例外键
		Query query = getSession().createQuery("update FlowIns fi set fi.flowNode = null where fi.flowNode.nodeId=:nodeId");
		query.setString("nodeId", id);
		query.executeUpdate();
		//删除任务实例外键
		query = getSession().createQuery("update TaskIns ti set ti.flowNode = null where ti.flowNode.nodeId=:nodeId");
		query.setString("nodeId", id);
		query.executeUpdate();
		
		delete(node);//删除步骤，级联删除授权
	}
	
	@Override
	public int findFlowNodeNextOrderCode(String flowId) {
		Query query = getSession().createQuery("select max(n.orderCode) from FlowNode as n where n.flowDef.flowId=:flowId");
		query.setString("flowId", flowId);
		Integer maxValue = (Integer)query.uniqueResult();
		
		return maxValue == null ? 0 : maxValue.intValue();
	}
	
	@Override
	public boolean testFirstNode(String flowDefId, String currentNodeId) {
		String hql = "select count(n) from FlowNode as n where n.flowDef.flowId=:flowDefId and n.orderCode < " +
				"(select n1.orderCode from FlowNode as n1 where n1.nodeId=:nodeId)";
		Query query = getSession().createQuery(hql);
		query.setString("flowDefId", flowDefId);
		query.setString("nodeId", currentNodeId);
		Long num = (Long)query.uniqueResult();
		return num.longValue() == 0;
	}
	
	public FlowNode findPreviousNode(String flowDefId, String currentNodeId) {
		String hql = "from FlowNode as n where n.flowDef.flowId=:flowDefId";
		if (currentNodeId != null) {
			hql += " and n.orderCode < (select n1.orderCode from FlowNode as n1 where n1.nodeId=:nodeId)";
		}
		hql += " order by n.orderCode desc";
		Query query = getSession().createQuery(hql);
		query.setString("flowDefId", flowDefId);
		if (currentNodeId != null) {
			query.setString("nodeId", currentNodeId);
		}
		query.setMaxResults(1);
		return (FlowNode)query.uniqueResult();
	}
	
	@Override
	public FlowNode findNextNode(String flowDefId, String currentNodeId) {
		String hql = "from FlowNode as n where n.flowDef.flowId=:flowDefId";
		if (currentNodeId != null) {
			hql += " and n.orderCode > (select n1.orderCode from FlowNode as n1 where n1.nodeId=:nodeId)";
		}
		hql += " order by n.orderCode";
		Query query = getSession().createQuery(hql);
		query.setString("flowDefId", flowDefId);
		if (currentNodeId != null) {
			query.setString("nodeId", currentNodeId);
		}
		query.setMaxResults(1);
		return (FlowNode)query.uniqueResult();
	}
	
	@SuppressWarnings("unchecked")
	@Override
	public List<TaskIns> findTasks(String userId, List<String> roleIds) {
		String hql = "select distinct(t) from TaskIns as t join t.flowNode.nodeAssigns as a where " +
//				"t.taskStatus<>:taskStatus and " +
				"(a.assignType=:assignUser and a.assignValue=:userId";
		if (roleIds != null && !roleIds.isEmpty()) {
			hql += " or a.assignType=:assignRole and a.assignValue in (:roleIds)";
		}
		hql += ") order by t.createTime desc";
		Query query = getSession().createQuery(hql);
//		query.setCharacter("taskStatus", TaskIns.TASK_STATUS_END);
		query.setCharacter("assignUser", NodeAssign.ASSIGN_TYPE_USER);
		query.setString("userId", userId);
		if (roleIds != null && !roleIds.isEmpty()) {
			query.setCharacter("assignRole", NodeAssign.ASSIGN_TYPE_USER);
			query.setParameterList("roleIds", roleIds);
		}
		return query.list();
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<TaskIns> findEndTasks(String flowInsId) {
		Query query = getSession().createQuery("select ti from TaskIns as ti where " +
				"ti.flowIns.insId=:flowInsId and ti.taskStatus=:taskStatus order by ti.createTime");
		query.setString("flowInsId", flowInsId);
		query.setCharacter("taskStatus", TaskIns.TASK_STATUS_END);
		return query.list();
	}
}